package com.imooc.bilibili.following.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.imooc.bilibili.constant.user.UserConstant;
import com.imooc.bilibili.domain.following.FollowingGroup;
import com.imooc.bilibili.domain.following.UserFollowing;
import com.imooc.bilibili.domain.user.User;
import com.imooc.bilibili.domain.user.UserInfo;
import com.imooc.bilibili.exception.ConditionException;
import com.imooc.bilibili.following.service.FollowingGroupService;
import com.imooc.bilibili.following.service.UserFollowingService;
import com.imooc.bilibili.mapper.following.FollowingGroupMapper;
import com.imooc.bilibili.mapper.following.UserFollowingMapper;
import com.imooc.bilibili.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author gcq
 * @Create 2022-05-23
 */
@Service
public class UserFollowingServiceImpl extends ServiceImpl<UserFollowingMapper, UserFollowing> implements UserFollowingService {

    @Autowired
    UserFollowingMapper userFollowingMapper;

    @Autowired
    UserService userService;

    @Autowired
    FollowingGroupService followingGroupService;

    @Autowired
    FollowingGroupMapper followingGroupMapper;

    @Transactional
    @Override
    public void addUserFollowings(UserFollowing userFollowing) {
        Long groupId = userFollowing.getGroupId();
        if (groupId == null) {
            FollowingGroup followingGroup = followingGroupService.getByType(UserConstant.USER_FOLLOWING_GROUP_TYPE_DEFAULT);
            userFollowing.setGroupId(followingGroup.getId());
        } else {
            FollowingGroup followingGroup = followingGroupService.getById(groupId);
            if (followingGroup == null) {
                throw new ConditionException("关注分组不存在");
            }
        }
        // 查询被关注用户是否存在
        Long followingId = userFollowing.getFollowingId();
        User user = userService.getById(followingId);
        if (user == null) {
            throw new ConditionException("关注的用户不存在!");
        }
        // 防止用户重复添加，先删除，后添加
        QueryWrapper<UserFollowing> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", userFollowing.getUserId());
        queryWrapper.eq("followingId", userFollowing.getFollowingId());
        userFollowingMapper.delete(queryWrapper);
        userFollowing.setCreateTime(new Date());
        userFollowingMapper.insert(userFollowing);
    }

    /**
     * 第一步：获取关注的用户列表
     * 第二步：根据关注用户id查询关注用户的基本信息
     * 第三步：将关注用户按照关注分组进行分类
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public List<FollowingGroup> getUserFollowings(Long userId) {
        // 获取用户关注列表
        QueryWrapper<UserFollowing> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", userId);
        List<UserFollowing> userFollowingList = userFollowingMapper.selectList(queryWrapper);

        // 得到所有关注用户Id
        Set<Long> followingUserIds = userFollowingList.stream().map(UserFollowing::getFollowingId).collect(Collectors.toSet());

        // 获取所有关注用户信息
        List<UserInfo> userInfoList = new ArrayList<>();
        if (followingUserIds.size() > 0) {
            userInfoList = userService.getUserInfoByUserIds(followingUserIds);
        }
        // 获取用户关注的【用户】的具体信息
        for (UserFollowing userFollowing : userFollowingList) {
            for (UserInfo userInfo : userInfoList) {
                if (userFollowing.getFollowingId().equals(userInfo.getUserId())) {
                    userFollowing.setUserInfo(userInfo);
                }
            }
        }

        // 获取当前用户分组信息
        QueryWrapper<FollowingGroup> followingGroupQueryWrapper = new QueryWrapper<>();
        followingGroupQueryWrapper.eq("userId", userId);
        followingGroupQueryWrapper.in("type", (Object) UserConstant.USER_GROUP_ALL_TYPE);
        List<FollowingGroup> groupList = followingGroupService.list(followingGroupQueryWrapper);

        // 全部关注信息
        FollowingGroup allGroup = new FollowingGroup();
        allGroup.setName(UserConstant.USER_FOLLOWING_GROUP_ALL_NAME);
        allGroup.setFollowingUserInfoList(userInfoList);

        List<FollowingGroup> result = new ArrayList<>();
        result.add(allGroup);
        // 获取用户对应分组下的所有关注用户
        for (FollowingGroup followingGroup : groupList) {
            // 当前分组下的所有关注用户
            List<UserInfo> infoList = new ArrayList<>();
            for (UserFollowing userFollowing : userFollowingList) {
                if (followingGroup.getId().equals(userFollowing.getGroupId())) {
                    infoList.add(userFollowing.getUserInfo());
                }
            }
            followingGroup.setFollowingUserInfoList(infoList);
            result.add(followingGroup);
        }
        return result;
    }

    /**
     * 1、获取当前用户的粉丝列表
     *  粉丝：别的用户关注了你，别的用户就是你的粉丝
     * 2、根据粉丝的用户id查询基本信息
     * 3、查询当前用户是否已关注该粉丝
     *
     * @param userId 当前用户Id
     * @return 结果
     */
    @Override
    public List<UserFollowing> getUserFans(Long userId) {
        // 当前用户粉丝列表
        QueryWrapper<UserFollowing> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("followingId", userId);
        List<UserFollowing> fanList = userFollowingMapper.selectList(queryWrapper);

        // 粉丝列表详细信息
        Set<Long> fanIdSet = fanList.stream().map(UserFollowing::getUserId).collect(Collectors.toSet());
        List<UserInfo> userInfoList = new ArrayList<>();
        if (fanIdSet.size() > 0) {
            userInfoList = userService.getUserInfoByUserIds(fanIdSet);
        }

        // 当前用户关注的用户列表
        List<UserFollowing> followingList = userFollowingMapper.selectList(new QueryWrapper<UserFollowing>()
                .eq("userId", userId));

        // 当前用户粉丝列表 当前用户关注的用户列表，进行比较就能知道，那些用户是否关注过
        for (UserFollowing fan : fanList) { // 当前用户粉丝列表
            // 获取粉丝列表详细信息
            for (UserInfo userInfo : userInfoList) { // 粉丝【用户】详细信息列表
                if (fan.getUserId().equals(userInfo.getUserId())) { // 设置粉丝的详细信息
                    userInfo.setFollowed(false); // 默认没有互相关注
                    fan.setUserInfo(userInfo);
                }
            }

            // 是否互粉
            // B C D 关注了 A
            // A 关注了 B C D
            for (UserFollowing following : followingList) { // 当前用户关注的用户列表
                // 当前用户关注的用户列表中是否关注了该粉丝，如果关注了那么就是互相关注
                // 被关注id 等于 粉丝的userid 互粉 你关注了我 我关注你
                if (following.getFollowingId().equals(fan.getUserId())) {
                    fan.getUserInfo().setFollowed(true); // 关注了当前用户
                }
            }
        }
        return fanList;
    }

    @Override
    public Long addUserFollowingGroups(FollowingGroup followingGroup) {
        followingGroup.setCreateTime(new Date());
        followingGroup.setType(UserConstant.USER_FOLLOWING_GROUP_TYPE_USER);
        followingGroupMapper.insert(followingGroup);
        return followingGroup.getId();
    }

    @Override
    public List<FollowingGroup> getUserFollowingGroups(Long userId) {
        return followingGroupMapper.selectList(new QueryWrapper<FollowingGroup>().eq("userId", userId));
    }

    @Override
    public List<UserInfo> checkFollowingStatus(List<UserInfo> userInfoList, Long userId) {
        // 当前用户关注的用户
        List<UserFollowing> userFollowingList = userFollowingMapper.selectList(new QueryWrapper<UserFollowing>()
                .eq("userId", userId));
        for (UserFollowing userFollowing : userFollowingList) {
            for (UserInfo userInfo : userInfoList) {
                // 是否有用户关注过的用户
                if(userFollowing.getFollowingId().equals(userInfo.getUserId())) {
                    userInfo.setFollowed(true);
                }
            }
        }
        return userInfoList;
    }
}